package com.sssre.business.util;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 浪兎兎
 * @create 2025-05-15-20:53
 */
public abstract class EffectiveTimeUtil {
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");

    /**
     * 计算可用时间
     * @param startTimeStr 开始时间
     * @param endTimeStr 结束时间
     * @param disabledTimes 禁用时间
     * @return 可用时间
     */
    public static List<String> getAvailableTimeSlots(String startTimeStr, String endTimeStr, List<String> disabledTimes) {
        // 解析输入时间
        LocalTime startTime = LocalTime.parse(startTimeStr, TIME_FORMATTER);
        LocalTime endTime = LocalTime.parse(endTimeStr, TIME_FORMATTER);

        // 将禁用时间转换为Set以便快速查找
        Set<LocalTime> disabledTimeSet = new HashSet<>();
        for (String disabled : disabledTimes) {
            disabledTimeSet.add(LocalTime.parse(disabled, TIME_FORMATTER));
        }

        List<LocalTime> availableTimes = new ArrayList<>();
        LocalTime current = startTime;

        // 生成所有可能的时间段（整点或半点）
        while (!current.isAfter(endTime)) {
            // 只考虑整点或半点
            if (current.getMinute() == 0 || current.getMinute() == 30) {
                if (!disabledTimeSet.contains(current)) {
                    availableTimes.add(current);
                }
            }

            // 增加30分钟
            current = current.plusMinutes(30);

            // 处理结束时间正好是整点或半点的情况
            if (current.isAfter(endTime)) {
                if ((endTime.getMinute() == 0 || endTime.getMinute() == 30)
                        && !disabledTimeSet.contains(endTime)
                        && !endTime.isBefore(startTime)) {
                    availableTimes.add(endTime);
                }
                break;
            }
        }

        return availableTimes.stream().map(date -> date.format(TIME_FORMATTER)).collect(Collectors.toList());
    }

    /**
     * 时间范围
     * @param times 时间列表
     * @return 可用的时间范围
     */
    private static List<String> mergeConsecutiveTimes(List<LocalTime> times) {
        if (times.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> mergedSlots = new ArrayList<>();
        LocalTime start = times.get(0);
        LocalTime prev = start;

        for (int i = 1; i < times.size(); i++) {
            LocalTime current = times.get(i);
            // 检查是否连续（相差30分钟）
            if (prev.plusMinutes(30).equals(current)) {
                prev = current;
            } else {
                // 不连续时，添加当前区间
                mergedSlots.add(formatTimeRange(start, prev));
                start = current;
                prev = current;
            }
        }
        // 添加最后一个区间
        mergedSlots.add(formatTimeRange(start, prev));

        return mergedSlots;
    }

    /**
     * 拼接时间范围
     * @param start 开始时间
     * @param end 结束时间
     * @return 时间范围
     */
    private static String formatTimeRange(LocalTime start, LocalTime end) {
        return start.format(TIME_FORMATTER) + " - " + end.format(TIME_FORMATTER);
    }

    public static void main(String[] args) {
        // 示例用法
        String startTime = "08:00";
        String endTime = "12:00";
        List<String> disabledTimes = Arrays.asList("09:00", "10:30");

        List<String> availableSlots = getAvailableTimeSlots(startTime, endTime, disabledTimes);

        System.out.println("可选择的时间段:");
        for (String slot : availableSlots) {
            System.out.println(slot);
        }

        // 测试合并功能
        List<LocalTime> testTimes = new ArrayList<>();
        testTimes.add(LocalTime.parse("08:30"));
        testTimes.add(LocalTime.parse("09:00"));
        testTimes.add(LocalTime.parse("09:30"));
        testTimes.add(LocalTime.parse("10:30"));
        testTimes.add(LocalTime.parse("11:00"));
        testTimes.add(LocalTime.parse("13:00"));

        System.out.println("\n测试合并功能:");
        System.out.println("输入: [08:30, 09:00, 09:30, 10:30, 11:00, 13:00]");
        System.out.println("输出: " + mergeConsecutiveTimes(testTimes));
    }
}
